package org.jeecg.common.job;

import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.COSMOS;
import org.jeecg.common.StartedAppListener;
import org.jeecg.common.job.annotation.CustomJob;
import org.jeecg.common.job.data.service.IJobService;
import org.jeecg.common.job.data.vo.JobInfoVo;
import org.jeecg.common.job.enums.JobConstants;
import org.jeecg.common.util.BeanUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;

@Slf4j
@Component
@Configuration
public class JobBundleConfig implements StartedAppListener.AccessPoint {

    private static Logger LG = LoggerFactory.getLogger(JobBundleConfig.class);


    public JobBundleConfig() {}

    @Override
    public void completed(String... args) {
        IJobService jobService = COSMOS.getBean(IJobService.class);
        try {
            this.scanJobs(jobService);
            jobService.cacheSelectJob();
        } catch (Exception e) {
        	LG.error("扫描定时任务报错:{}", e);
        }

        // 添加服务监控
        JobManageCenter.addJob("-1","0/30 * * * * ? ", "serverMonitor", "checkServer", 1, JobConstants.NODE_NAME, new Date());
        // 每月1日的凌晨1点执行一次
        JobManageCenter.addJob("-2", "0 0 1 1 * ? * ", "serverMonitor", "deleteJobLogs", 1, JobConstants.NODE_NAME, new Date());
    }

    /**
     * 扫描定时任务模块
     *
     * @return
     */
    private void scanJobs(IJobService jobService) throws Exception {
        ResourcePatternResolver rpr = new PathMatchingResourcePatternResolver();
        // classpath*:带*号会找jar中的class
        Resource[] res = rpr.getResources("classpath*:org/jeecg/**/*.class");
        if (res == null) {
            return;
        }
        for (Resource resource : res) {
            // 然后根据resource取clas路径就行
            String className = BeanUtil.handleClassPath("org.jeecg", resource.getURL().getPath());
            if(className == null || className.startsWith("org.jeecg.common")){
                continue;
            }
            Class<?> cls = Class.forName(className);
            Method[] methods = cls.getMethods();
            for (Method method : methods) {
                CustomJob dbTable = method.getAnnotation(CustomJob.class);
                if (dbTable == null) {
                    continue;
                }
                // 添加服务监控
                String beanName = toLowerCaseFirstOne(cls.getSimpleName());
                String methodName = method.getName();
                JobInfoVo jobInfoVo = jobService.findJobInfoVo(beanName, methodName);
                if(jobInfoVo == null){
                    jobInfoVo = new JobInfoVo();
                    jobInfoVo.setBeanName(beanName);
                    jobInfoVo.setBeanMethod(methodName);
                    jobInfoVo.setCycleTime(dbTable.defaultCronExpression());
                    jobInfoVo.setExecuteMode(1);
                    jobInfoVo.setName(dbTable.name());
                    jobInfoVo.setNodeName(JobConstants.NODE_NAME);
                    jobInfoVo.setStatus(JobConstants.JobStatus.NO.getId());
                    jobService.save(jobInfoVo);
                }

                if(jobInfoVo.getStatus().equals(JobConstants.JobStatus.NO.getId())){
                    JobManageCenter.addJob(jobInfoVo.getId(), jobInfoVo.getCycleTime(), jobInfoVo.getBeanName(), jobInfoVo.getBeanMethod(), 1, JobConstants.NODE_NAME, new Date());
                }
            }
        }
    }

    public static String toLowerCaseFirstOne(String s) {
        if (Character.isLowerCase(s.charAt(0))) {
            return s;
        } else {
            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
        }
    }
}
